<template>
    <div id="container"></div>
</template>
<script>
import { Graph, Node, Path, Cell, Shape, Addon } from '@antv/x6'
import '@antv/x6-vue-shape'
import { saveProcess, updateProcess, listProcess, getProcessInfo, deleteProcess, getX6GraphData, listHistoryForInst,listHistoryGraphForInst } from "@/api/activiti/customprocess";
import database from './nodeTheme/database.vue'
import condition from './nodeTheme/condition.vue'
import onlyout from './nodeTheme/onlyOut.vue'
import onlyin from './nodeTheme/onlyIn.vue'
export default {
    name: 'ShowProcess',
    components: {},
    props: {
        instanceId: {
            type: String,
        }
    },
    data() {
        return {
            graph: '',
            graphData: '',
            historyData: ''
        }
    },
    mounted() {
        this.showGraph()
    },
    methods: {
        async showGraph() {
            this.initGraph()
            await this.getX6GraphDataFn()
            console.log('show-process: data is', this.graphData)
            this.init(JSON.parse(this.graphData))
            await this.listHistoryForInstFn()
            this.showNodeStatus(this.historyData)
            // this.showNodeStatus(Object.assign([], nodeStatusList))
            this.graph.centerContent()
        },
        initGraph() {
            // 注册节点
            Graph.registerNode(
                'dag-condition',
                {
                    inherit: 'vue-shape',
                    width: 180,
                    height: 36,
                    component: {
                        template: `<condition />`,
                        components: {
                            condition
                        }
                    },
                    ports: {
                        groups: {
                            top: {
                                position: 'top',
                                attrs:
                                {
                                    circle: {
                                        r: 4,
                                        magnet: true,
                                        stroke:
                                            '#C2C8D5',
                                        strokeWidth: 1,
                                        fill: '#fff'
                                    }
                                }
                            },
                            bottom: {
                                position: 'bottom',
                                attrs: {
                                    circle: {
                                        r: 4,
                                        magnet:
                                            true,
                                        stroke: '#C2C8D5',
                                        strokeWidth: 1,
                                        fill: '#fff'
                                    }
                                }
                            }
                        }
                    }
                },
                true
            )

            Graph.registerNode(
                'start-event',
                {
                    inherit: 'vue-shape',
                    width: 180,
                    height: 36,
                    component: {
                        template: `<onlyout />`,
                        components: {
                            onlyout
                        }
                    },
                },
                true
            )

            Graph.registerNode(
                'end-event',
                {
                    inherit: 'vue-shape',
                    width: 180,
                    height: 36,
                    component: {
                        template: `<onlyout />`,
                        components: {
                            onlyout
                        }
                    },
                },
                true
            )

            Graph.registerNode(
                'user-task',
                {
                    inherit: 'vue-shape',
                    width: 180,
                    height: 36,
                    component: {
                        template: `<onlyin />`,
                        components: {
                            onlyin
                        }
                    },
                    ports: {
                        groups: {
                            top: {
                                position: 'top',
                                attrs:
                                {
                                    circle: {
                                        r: 4,
                                        magnet: true,
                                        stroke:
                                            '#C2C8D5',
                                        strokeWidth: 1,
                                        style: {
                                            visibility: 'hidden',
                                        },
                                        fill: '#fff'
                                    }
                                }
                            },
                            left: {
                                position: 'left',
                                attrs: {
                                    circle: {
                                        r: 4,
                                        magnet:
                                            true,
                                        stroke: '#C2C8D5',
                                        strokeWidth: 1,
                                        style: {
                                            visibility: 'hidden',
                                        },
                                        fill: '#fff'
                                    }
                                }
                            },
                            bottom: {
                                position: 'bottom',
                                attrs: {
                                    circle: {
                                        r: 4,
                                        magnet:
                                            true,
                                        stroke: '#C2C8D5',
                                        strokeWidth: 1,
                                        style: {
                                            visibility: 'hidden',
                                        },
                                        fill: '#fff'
                                    }
                                }
                            },
                            right: {
                                position: 'right',
                                attrs: {
                                    circle: {
                                        r: 4,
                                        magnet:
                                            true,
                                        stroke: '#C2C8D5',
                                        strokeWidth: 1,
                                        style: {
                                            visibility: 'hidden',
                                        },
                                        fill: '#fff'
                                    }
                                }
                            },
                        },
                        items: [
                            {
                                group: 'top' // 指定分组名称
                            },
                            {
                                group: 'left' // 指定分组名称
                            },
                            {
                                group: 'bottom' // 指定分组名称
                            },
                            {
                                group: 'right'
                            }
                        ]
                    },
                },
                true
            )




            Graph.registerNode(
                'dag-node',
                {
                    inherit: 'vue-shape',
                    width: 180,
                    height: 36,
                    component: {
                        template: `<database />`,
                        components: {
                            database
                        }
                    },
                    ports: {
                        groups: {
                            top: {
                                position: 'top',
                                attrs:
                                {
                                    circle: {
                                        r: 4,
                                        magnet: true,
                                        stroke:
                                            '#C2C8D5',
                                        strokeWidth: 1,
                                        fill: '#fff'
                                    }
                                }
                            },
                            bottom: {
                                position: 'bottom',
                                attrs: {
                                    circle: {
                                        r: 4,
                                        magnet:
                                            true,
                                        stroke: '#C2C8D5',
                                        strokeWidth: 1,
                                        fill: '#fff'
                                    }
                                }
                            }
                        }
                    }
                },
                true
            )

            Graph.registerEdge(
                'dag-edge',
                {
                    inherit: 'edge',
                    data: {
                        bpmnType: 'sequenceFlow'
                    },
                    router: {
                        name: 'orth',
                    },
                    attrs: {
                        line: {
                            stroke: '#C2C8D5',
                            strokeWidth: 2,
                            targetMarker: {
                                name: 'block',
                                width: 12,
                                height: 8
                            }
                        }
                    }
                },
                true
            )
            const graph = new Graph({
                container: document.getElementById('container'),
                scroller: true,
                interacting: false,
                connecting: {
                    router: 'orth',
                },
            })
            this.graph = graph
            graph.on('node:change:data', ({ node }) => {
                // const edges = graph.getOutgoingEdges(node)
                // const { status } = node.getData()
                // edges?.forEach((edge) => {
                //     if (status === 'running') {
                //         edge.attr('line/strokeDasharray', 5)
                //         edge.attr('line/style/animation', 'running-line 30s infinite linear')
                //     } else {
                //         edge.attr('line/strokeDasharray', '')
                //         edge.attr('line/style/animation', '')
                //     }
                // })
            })
        },
        async getX6GraphDataFn() {
            let response = await getX6GraphData(this.instanceId);
            console.log('response ', response)
            this.graphData = response.msg;
        },
        async listHistoryForInstFn() {
            let response = await listHistoryGraphForInst(this.instanceId);
            console.log('history res ', response)
            this.historyData = response.data;
        },
        async showNodeStatus(statusList) {
            statusList.forEach((item) => {
                const { actId, status } = item
                const node = this.graph.getCellById(actId)
                const data = node.getData()
                this.$nextTick(() => {
                    node.setData({
                        ...data,
                        status: status
                    })
                    this.edgeStyleChange(node)
                })
            })
        },
        edgeStyleChange(node) {
            const edges = this.graph.getOutgoingEdges(node)
            const { status } = node.getData()
            edges?.forEach((edge) => {
                if (status === 'running') {
                    edge.attr('line/strokeDasharray', 5)
                    edge.attr('line/style/animation', 'running-line 30s infinite linear')
                } else if (status == 'success') {
                    let nextStatus = this.getNextNodeStatus(edge)
                    if (nextStatus == 'success' || nextStatus == 'running') {
                        edge.attr('line/stroke', '#52c41a')
                        edge.attr('line/strokeDasharray', '')
                        edge.attr('line/style/animation', '')
                    }
                }
            })
        },
        getNextNodeStatus(edge) {
            let nextNodeId = edge.target.cell;
            let historyNode = this.historyData.find(o => o.actId == nextNodeId);
            if(historyNode != undefined) {
                return historyNode.status
            } else {
                return 'unknown'
            }
        },
        // 初始化节点/边
        init(data = []) {
            const cells = []
            data.cells.forEach((item) => {
                if (item.shape === 'dag-edge') {
                    cells.push(this.graph.createEdge(item))
                } else {
                    delete item.component
                    item.data = {
                        ...item.data,
                        status: 'default'
                    }
                    console.log('init item', item)
                    let node = this.graph.createNode(item)
                    // const data = node.getData()
                    // node.setData({
                    //     ...data,
                    //     status: 'default'
                    // })
                    cells.push(node)
                }
            })
            this.graph.resetCells(cells)
            this.graph.centerContent()
        },
    }
}
</script>
<style>
#container {
    width: 800px;
    height: 600px;
}
</style>